package fr.inria.arles.tempManagement.RFID;

import java.nio.ByteBuffer;
import java.util.List;
import java.util.Properties;
import javax.smartcardio.Card;
import javax.smartcardio.CardChannel;
import javax.smartcardio.CardException;
import javax.smartcardio.CardTerminal;
import javax.smartcardio.TerminalFactory;
import static fr.inria.arles.temperatureManagement.Constants.*;
import static fr.inria.arles.temperatureManagement.Utility.*;

/**
 *
 * @author ajay chhatwal
 */
public class RFIDCardReader {

    private String myPartition;

    public RFIDCardReader(String myPartition) {
        this.myPartition = myPartition;
    }

    public void read() {

        try {

            CardTerminal terminal = null;
            System.out.println("Waiting for card ...");
            // Get reference to our terminal
            TerminalFactory factory = TerminalFactory.getDefault();
            List<CardTerminal> terminals = factory.terminals().list();

            String readerName = "";

            for (int i = 0; i < terminals.size(); i++) {

                readerName = terminals.get(i).getName();
                //  System.out.println(readerName);
                if (readerName.equalsIgnoreCase("ACS ACR122U PICC Interface 0")) {
                    terminal = terminals.get(i);
                }
            }

            if (terminal == null) {
                System.out.println("Specified Card Reader not found");
                return;
            }
            while (true) {
                // Establish a connection with the card
                //  System.out.println("Waiting for a card..");
                terminal.waitForCardPresent(0);

                Card card = terminal.connect("*");
                CardChannel channel = card.getBasicChannel();

                // Start with something simple, read UID, kinda like Hello World!
                byte[] baReadUID = new byte[5];

                baReadUID = new byte[]{(byte) 0xFF, (byte) 0xCA, (byte) 0x00,
                            (byte) 0x00, (byte) 0x00};

                String rfid = send(baReadUID, channel);
                System.out.println("Card Read. UID: " + rfid);
                terminal.waitForCardAbsent(0);
                RFIDProcessor.processRFID(rfid, myPartition);

            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }

    }

    private String send(byte[] cmd, CardChannel channel) {

        String res = "";

        byte[] baResp = new byte[258];
        ByteBuffer bufCmd = ByteBuffer.wrap(cmd);
        ByteBuffer bufResp = ByteBuffer.wrap(baResp);

        // output = The length of the received response APDU
        int output = 0;

        try {

            output = channel.transmit(bufCmd, bufResp);

        } catch (CardException ex) {
            ex.printStackTrace();
        }

        for (int i = 0; i < output; i++) {
            res += String.format("%02X", baResp[i]);
            // The result is formatted as a hexadecimal integer
        }

        return res;
    }

    public static void main(String[] args) {
         Properties properties = new Properties();
		loadProperties(properties, PROP_FILE);
        for (int i = 0; i < args.length - 1; i += 2) {
            boolean valid = processArg(properties,args[i], "PROCESSING_NODE_IP", args[i + 1])
                    && processArg(properties,args[i], "PROCESSING_NODE_PORT", args[i + 1])
                    && processArg(properties,args[i], "DEFAULT_TEMP_SETTING", args[i + 1]);
            if (!valid) {
                System.out.println("Invalid argument :" + args[i]);
            }
        }

        PROCESSING_NODE_IP = properties.getProperty("PROCESSING_NODE_IP",
                PROCESSING_NODE_IP);
        PROCESSING_NODE_PORT = Integer.parseInt(properties.getProperty(
                "PROCESSING_NODE_PORT", PROCESSING_NODE_PORT + ""));
        DEFAULT_TEMP_SETTING = Double.parseDouble(properties.getProperty(
                "DEFAULT_TEMP_SETTING", DEFAULT_TEMP_SETTING + ""));



        new RFIDCardReader("room 27").read();
    }
}
